//
// Created by yyl on 2021/11/30.
//

#ifndef GLSL3LIB_BASEVIDEOSHADER_H
#define GLSL3LIB_BASEVIDEOSHADER_H

#include <BaseEntity.h>
#include "../shader/BaseShader.h"
#include "../render/MatrixConvert.h"

class BaseVideoShader : public BaseShader {
public:
    //1. 顶点数组对象(Vertex Array Object, VAO)
    void createVAO() {
        LOGI("createVAO");
//        GLuint VAO;
        glGenVertexArrays(1, &VAO);
        glBindVertexArray(VAO);
    }

    //2. 顶点缓冲对象(Vertex Buffer Objects, VBO)
    void createVBO() {
        LOGI("createVBO");
        float vertices[] = {
                // 位置X   Y   Z    //纹理坐标 S T
                1.0f, 1.0f, 0.0f, 1.0f, 1.0f,   // 右上
                1.0f, -1.0f, 0.0f, 1.0f, 0.0f,  // 右下
                -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, // 左下
                -1.0f, 1.0f, 0.0f, 0.0f, 1.0f   // 左上
        };
        glGenBuffers(1, &VBO);
        glBindBuffer(GL_ARRAY_BUFFER, VBO);
        glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

        //位置属性指针XYZ   对应vertex.vert中的变量 layout(location = 0)
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void *) 0);
        glEnableVertexAttribArray(0);

        //   对应vertex.vert中的变量 layout(location = 1)
        glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float),
                              (void *) (3 * sizeof(float)));
        glEnableVertexAttribArray(1);
    }


    //3. 索引缓冲对象(Element Buffer Object，EBO，也叫Index Buffer Object，IBO)
//面试：索引缓冲对象:主要解决顶点坐标重复，优化顶点坐标
    void createEBO() {
        // 注意索引从0开始!
        GLuint indices[] = {
                0, 1, 2, // 第一个三角形
                0, 2, 3  // 第二个三角形
        };
        glGenBuffers(1, &EBO);
        //5.复制我们的索引数组到一个索引缓冲中，供OpenGL使用
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
        //把索引数据复制到缓冲的内存中
        //把[indices]数据 复制到缓冲的内存 给<缓冲buffer>然后上面的<缓冲buffer>EBO就有值了
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
    }

    GLuint textureY;
    GLuint textureU;
    GLuint textureV;
    GLuint textureUV;

    void bindTextureYUV() {
        if (renderImage.ppPlane[0] != nullptr) {
            LOGI("bindTextureImage 纹理");
            glBindTexture(GL_TEXTURE_2D, textureID);
            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, renderImage.width, renderImage.height, 0,
                         GL_RGBA,
                         GL_UNSIGNED_BYTE, renderImage.ppPlane[0]);
            //自动生成所有需要的多级渐远纹理   多级渐远纹理是缩小时图像采样的方式
            //生成了纹理和相应的多级渐远纹理后，需要释放图像的内存
            glGenerateMipmap(GL_TEXTURE_2D);
            NativeImageUtil::FreeNativeImage(&renderImage);
            glBindTexture(GL_TEXTURE_2D, GL_NONE);

            glBindTexture(GL_TEXTURE_2D, textureY);
            glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE,
                         renderImage.width, renderImage.height, 0,
                         GL_LUMINANCE, GL_UNSIGNED_BYTE, renderImage.ppPlane[0]);

            glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
            glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
            glBindTexture(GL_TEXTURE_2D, GL_NONE);


            glBindTexture(GL_TEXTURE_2D, textureUV);
            glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA,
                         renderImage.width >> 1, renderImage.height >> 1, 0,
                         GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, renderImage.ppPlane[1]);
            glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
            glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
            glBindTexture(GL_TEXTURE_2D, GL_NONE);
        }else{
            LOGI("bindTextureImage 没有纹理");
        }

    }
private:


};

#endif //GLSL3LIB_BASEVIDEOSHADER_H
